#include <wx/wxprec.h>

#ifdef __BORLANDC__
	#pragma hdrstop
#endif

#ifndef WX_PRECOMP
	#include <wx/wx.h>
#endif
#include <wx/wfstream.h>
#include <wx/cmdline.h>
#include <wx/filename.h>
#include "myapp.h"
#include "kakeibo.h"
#include "../config.h"

IMPLEMENT_APP(MyApp)

MyApp::MyApp() : locale(wxLANGUAGE_DEFAULT)
{
#ifndef __WXDEBUG__
	wxLog::EnableLogging(false);
#endif
	isnew = true;
	ischanged = false;
}
bool MyApp::OnInit()
{
	/*if (!wxApp::OnInit())
		return false;*/
	this->SetAppName(_T(PACKAGE_NAME));
	this->SetVendorName(CREATOR);

#ifdef __UNIX__
	wxString pdd(_T(PACKAGE_DATA_DIR));
	pdd.Replace(_T("/share"),_T(" "));
	pdd.Trim();
	stpath.SetInstallPrefix(pdd);
#endif
	//locale.Init(wxLANGUAGE_DEFAULT);
	locale.AddCatalogLookupPathPrefix(_T("."));
	locale.AddCatalogLookupPathPrefix(_T(PACKAGE_LOCALE_DIR));
	locale.AddCatalog(BINTITLE);


	//initialize path string
	pathstr.Add(_T("share"));
	pathstr.Add(_T("doc"));
	pathstr.Add(_T("locale"));
	pathstr.Add(_T(PACKAGE_NAME));
	pathstr.Add(_T("icon"));
	
	//set system images
	wxInitAllImageHandlers();
	icoList = new wxImageList(16,16,true);
	icoDList = new wxImageList(32,32,true);
	sysicoList = new wxImageList(16,16,true);
	wxFileName sysicopath;
	sysicopath.AssignDir(stpath.GetResourcesDir());
#ifdef __WXMSW__
	sysicopath.AppendDir(wxGetApp().GetPathElement(P_SHARE));
	sysicopath.AppendDir(wxGetApp().GetPathElement(P_APPNAME));
#endif
	sysicopath.AppendDir(wxGetApp().GetPathElement(P_ICON));

	sysicopath.SetFullName(APPSYSICONS);
	LoadIconImage(sysicopath.GetFullPath(),sysicoList,16,16);

	// Parsing the command line
	static const wxCmdLineEntryDesc cmdLineDesc[] = {
		{ wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), _("show this help message"),
		  wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
		{ wxCMD_LINE_PARAM, 0, 0, _T("files"),
		  wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
#ifdef __WXDEBUG__
		{ wxCMD_LINE_PARAM, 0, 0, _T("Test Date"),
		  wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
#endif
		{ wxCMD_LINE_NONE }
	};
	wxCmdLineParser parser(cmdLineDesc, this->argc, this->argv);
	//this->OnInitCmdLine(parser);
	if (parser.Parse() != 0) {
		return false;
	}

	//read initial setting file
	wxFileName fullpath;
	wxString path = stpath.GetUserDataDir();
	fullpath.AssignDir(path);
	//Msgbox(stpath.GetUserDataDir()+_T("\n")+stpath.GetDataDir()+_T("\n")+
	//	stpath.GetApplicationDir(),NULL);
	if (!wxFileName::DirExists(fullpath.GetPath())) {
		wxFileName::Mkdir(fullpath.GetPath());
	}
	wxString filename = wxString::Format(_T("%s.ini"),BINTITLE);
	fullpath.SetFullName(filename);

	//create main window
	MyFrame *frame = new MyFrame(APPTITLE);
	frame->SetDropTarget(new DDFile(frame));
	SetTopWindow(frame);
	LoadIni(fullpath.GetFullPath());
	frame->CreateRecent();
	if (parser.GetParamCount() > 0) {
		frame->Open_File(parser.GetParam(0));
	}
	//frame->Centre();
	frame->Show(true);
	
	/*wxString selects[] = {
		_("New"), _("Open")
	};
	int sel = wxGetSingleChoiceIndex(_("What's you want to do?"),
	APPTITLE,2,selects,frame,-1,-1,true,150,100);*/

	return true;
}
int MyApp::OnExit()
{
	icoList->RemoveAll();
	icoList->UnRef();
	icoDList->RemoveAll();
	icoDList->UnRef();
	sysicoList->RemoveAll();
	sysicoList->UnRef();
	return 0;
}
wxSQLite3Database &MyApp::SQLDB(void)
{
	return dbkakeibo;
}
/*DB_kakeibo MyApp::AppDB(void)
{ 
	return mainDB;
}*/
const wxString &MyApp::GetFilePath(void)
{ 
	return DBFilePath; 
}
void MyApp::SetFilePath(wxString name) 
{ 
	DBFilePath = name; 
}
const wxString &MyApp::GetTempFilePath(void)
{ 
	return tempDBFilePath; 
}
void MyApp::SetTempFilePath(wxString name) 
{ 
	tempDBFilePath = name; 
}
bool MyApp::IsNewFile(void) 
{ 
	return isnew; 
}
void MyApp::SetNewFlag(bool flg) 
{ 
	isnew = flg; 
}
bool MyApp::IsChanged(void)
{
	return ischanged;
}
void MyApp::SetChangeFlag(bool flg)
{
	ischanged = flg;
}
void MyApp::LoadIni(const wxString &path)
{
	if (!wxFileName::FileExists(path)) {
		wxFile fl;
		fl.Create(path.c_str());
		fl.Close();
	}
	wxFileInputStream fis(path);
	config = new wxFileConfig(fis,wxConvUTF8);
	inipath = path;
	bool tbool;
	long t[2];

	MyFrame *frame = (MyFrame*)GetTopWindow();

	//---common setting
	config->Read(_T("/common/WindowMaximized"),&tbool,false);
	frame->Maximize(tbool);
	config->Read(_T("/common/ClientWidth"),&t[0],640);
	config->Read(_T("/common/ClientHeight"),&t[1],480);
	frame->SetSize(wxSize(t[0],t[1]));
	config->Read(_T("/common/Top"),&t[0]);
	config->Read(_T("/common/Left"),&t[1]);
	frame->SetPosition(wxPoint((int)t[0],(int)t[1]));

	//---recent file
	int recentcnt = (int)config->Read(_T("/recentfile/Count"),(long)0);
	AppDB.AppSetting.ClearRecent();
	for (int i = 0; i < recentcnt; i++) {
		AppDB.AppSetting.AddRecent(config->Read(StrF(_T("/recentfile/file%d"),i),wxEmptyString));
	}

	//---setting dialog
	//AppDB.AppSetting.SetUserName(config->Read(_T("/general/UserName"),wxEmptyString));
	AppDB.AppSetting.SetCurrencyUnit(config->Read(_T("/general/CurrencyUnit"),wxEmptyString));
	AppDB.AppSetting.SetStartWeekDay(config->Read(_T("/general/StartWeekDay"),(long)0));
	AppDB.AppSetting.SetIconPath(config->Read(_T("/general/IconPath"),wxEmptyString));
	/*wxFont font;
	font.SetDefaultEncoding((wxFontEncoding)config->Read(_T("/general/FontDefaultEncoding"),wxNORMAL_FONT->GetDefaultEncoding()));
	font.SetFaceName(config->Read(_T("/general/FontFaceName"),wxNORMAL_FONT->GetFaceName()));
	font.SetFamily((wxFontFamily)config->Read(_T("/general/FontFamily"),wxNORMAL_FONT->GetFamily()));
	font.SetPointSize(config->Read(_T("/general/FontPointSize"),wxNORMAL_FONT->GetPointSize()));
	font.SetStyle(config->Read(_T("/general/FontStyle"),wxNORMAL_FONT->GetStyle()));
	font.SetUnderlined(config->Read(_T("/general/FontUnderlined"),_T("0")) == _T("1") ? true : false);
	font.SetWeight((wxFontWeight)config->Read(_T("/general/FontWeight"),wxNORMAL_FONT->GetWeight()));*/
	//AppDB.AppSetting.SetFontInfo();
	config->Read(_T("/general/EncryptFile"),&tbool,false);
	AppDB.AppSetting.SetEncrypt(tbool);

	int holidaycnt = (int)config->Read(_T("/holiday/Count"),(long)0);
	for (int i = 0; i < holidaycnt; i++) {
		DB_holiday db;
		wxString datestr = config->Read(StrF(_T("/holiday/Holiday%d_Date"),i),wxEmptyString);
		wxDateTime hdate;
		hdate.ParseDate(datestr);
		if (!datestr.IsEmpty()) {
			db.SetDate(hdate);
			db.SetName(config->Read(StrF(_T("/holiday/Holiday%d_Name"),i),wxEmptyString));
			AppDB.AppSetting.AddHoliday(db);
		}
	}
	LoadIconImage(AppDB.AppSetting.GetIconPath(),icoList,16,16);
	LoadIconImage(AppDB.AppSetting.GetIconPath(),icoDList,32,32);

	//---print setting
	bool enable, useline;
	wxString headerfooter[3];
	bool options[4];
	wxPoint pos;
	config->Read(_T("/print/direction"),&t[0],(long)0);
	frame->GetPageSetupData()->GetPrintData().SetOrientation((int)(t[0]));
	config->Read(_T("/print/PaperType"),&t[1],(long)wxPAPER_NONE);
	frame->GetPageSetupData()->SetPaperId((wxPaperSize)t[1]);
	config->Read(_T("/print/MarginTop"),&(pos.y),(long)0);
	config->Read(_T("/print/MarginLeft"),&(pos.x),(long)0);
	frame->GetPageSetupData()->SetMarginTopLeft(pos);
	config->Read(_T("/print/MarginBottom"),&(pos.y),(long)0);
	config->Read(_T("/print/MarginRight"),&(pos.x),(long)0);
	frame->GetPageSetupData()->SetMarginBottomRight(pos);
	frame->SetReportTitle(config->Read(_T("/print/ReportTitle"),wxEmptyString));
	config->Read(_T("/print/EnableHeader"),&enable,true);
	config->Read(_T("/print/UseHeaderline"),&useline,false);
	for (int i = 0; i < WXSIZEOF(headerfooter); i++)
		headerfooter[i] = config->Read(StrF(_T("/print/headerstring%d"),(i+1)),wxEmptyString);
	frame->SetReportHeaderInfo(enable,useline,headerfooter);
	config->Read(_T("/print/EnableFooter"),&enable,true);
	config->Read(_T("/print/UseFooterline"),&useline,false);
	for (int i = 0; i < WXSIZEOF(headerfooter); i++)
		headerfooter[i] = config->Read(StrF(_T("/print/footerstring%d"),(i+1)),wxEmptyString);
	frame->SetReportFooterInfo(enable,useline,headerfooter);
	for (size_t i = 0; i < WXSIZEOF(options); i++)
		config->Read(StrF(_T("/print/options%d"),(i+1)),&(options[i]),false);
	frame->SetReportOptions(options);

}
void MyApp::SaveIni(void)
{
	wxFileOutputStream fos(inipath);
	MyFrame *frame = (MyFrame*)GetTopWindow();
	//---common setting
	config->Write(_T("/common/WindowMaximized"),frame->IsMaximized());
	config->Write(_T("/common/ClientWidth"),frame->GetSize().GetWidth());
	config->Write(_T("/common/ClientHeight"),frame->GetSize().GetHeight());
	config->Write(_T("/common/Top"),frame->GetPosition().x);
	config->Write(_T("/common/Left"),frame->GetPosition().y);

	//---recent file
	config->Write(_T("/recentfile/Count"),AppDB.AppSetting.GetRecentCount());
	for (int i = 0; i < AppDB.AppSetting.GetRecentCount(); i ++) {
		config->Write(StrF(_T("/recentfile/file%d"),i),AppDB.AppSetting.GetRecent(i));
	}

	//---setting dialog
	//config->Write(_T("/general/UserName"),AppDB.AppSetting.GetUserNames());
	config->Write(_T("/general/CurrencyUnit"),AppDB.AppSetting.GetCurrencyUnit());
	config->Write(_T("/general/StartWeekDay"),AppDB.AppSetting.GetStartWeekDay());
	config->Write(_T("/general/IconPath"),AppDB.AppSetting.GetIconPath());
	/*config->Write(_T("/general/FontDefaultEncoding"),AppDB.AppSetting.GetFontInfo().GetDefaultEncoding());
	config->Write(_T("/general/FontFaceName"),AppDB.AppSetting.GetFontInfo().GetFaceName());
	config->Write(_T("/general/FontFamily"),AppDB.AppSetting.GetFontInfo().GetFamily());
	config->Write(_T("/general/FontPointSize"),AppDB.AppSetting.GetFontInfo().GetPointSize());
	config->Write(_T("/general/FontStyle"),AppDB.AppSetting.GetFontInfo().GetStyle());
	config->Write(_T("/general/FontUnderlined"),AppDB.AppSetting.GetFontInfo().GetUnderlined() ? _T("1") : _T("0"));
	config->Write(_T("/general/FontWeight"),AppDB.AppSetting.GetFontInfo().GetWeight());*/
	config->Write(_T("/holiday/Count"),AppDB.AppSetting.GetHolidayCount());
	for (int i = 0; i < AppDB.AppSetting.GetHolidayCount(); i++) {
		config->Write(StrF(_T("/holiday/Holiday%d_Date"),i),
			AppDB.AppSetting.GetHoliday(i).GetDate().Format(DATEFORM));
		config->Write(StrF(_T("/holiday/Holiday%d_Name"),i),
			AppDB.AppSetting.GetHoliday(i).GetName());
	}
	config->Write(_T("/general/EncryptFile"),AppDB.AppSetting.GetEncrypt());

	//---print setting
	bool enable, useline;
	wxString headerfooter[3];
	bool options[4];
	config->Write(_T("/print/direction"),frame->GetPageSetupData()->GetPrintData().GetOrientation());
	config->Write(_T("/print/PaperType"),frame->GetPageSetupData()->GetPaperId());
	config->Write(_T("/print/MarginTop"),frame->GetPageSetupData()->GetMarginTopLeft().y);
	config->Write(_T("/print/MarginLeft"),frame->GetPageSetupData()->GetMarginTopLeft().x);
	config->Write(_T("/print/MarginBottom"),frame->GetPageSetupData()->GetMarginBottomRight().y);
	config->Write(_T("/print/MarginRight"),frame->GetPageSetupData()->GetMarginBottomRight().x);
	config->Write(_T("/print/ReportTitle"),frame->GetReportTitle());
	frame->GetReportHeaderInfo(&enable,&useline,headerfooter);
	config->Write(_T("/print/EnableHeader"),enable);
	config->Write(_T("/print/UseHeaderline"),useline);
	for (int i = 0; i < WXSIZEOF(headerfooter); i++) config->Write(StrF(_T("/print/headerstring%d"),(i+1)),headerfooter[i]);
	frame->GetReportFooterInfo(&enable,&useline,headerfooter);
	config->Write(_T("/print/EnableFooter"),enable);
	config->Write(_T("/print/UseFooterline"),useline);
	for (int i = 0; i < WXSIZEOF(headerfooter); i++) config->Write(StrF(_T("/print/footerstring%d"),(i+1)),headerfooter[i]);
	int optlen = frame->GetReportOptions(options);
	for (size_t i = 0; i < (size_t)optlen; i++) config->Write(StrF(_T("/print/options%d"),(i+1)),options[i]);

	config->Save(fos);
	delete config;
}
void MyApp::LoadIconImage(const wxString &path, wxImageList *list, int ws, int hs)
{
	if (!wxFileName::FileExists(path)) {
		return;
	}
	const int ICODEFSIZE = 32;
	wxImage allimage;
	allimage.LoadFile(path);
	wxRect rect;
	rect.SetWidth(ICODEFSIZE);
	rect.SetHeight(ICODEFSIZE);
	rect.SetX(0);
	rect.SetY(0);
	int wcnt = allimage.GetWidth() / ICODEFSIZE;
	int hcnt = allimage.GetHeight() / ICODEFSIZE;
	list->RemoveAll();
	for (int h = 0; h < hcnt; h++) {
		for (int w = 0; w < wcnt; w++) {
			wxImage img = allimage.GetSubImage(rect);
			wxBitmap bmp;
			if (ws == ICODEFSIZE) {
				bmp = wxBitmap(img);
			}else{
				bmp = wxBitmap(img.Rescale(ws,hs));
			}
			list->Add(bmp);
			rect.SetX(rect.GetX()+rect.GetWidth());
		}
		rect.SetY(rect.GetY()+rect.GetHeight());
	}
}
wxString MyApp::GetPathElement(size_t num)
{
	if (num >= pathstr.GetCount()) {
		return wxEmptyString;
	}else{
		return pathstr.Item(num);
	}
}
